<?php


namespace App\Services\Tools;


use App\Repositories\LogRepository;
use Illuminate\Support\Facades\Log;
use App\Models\MainDB\UserRecharge;
class WxPayXCXService
{
    protected $config;

    public function __construct(array $config = [])
    {
        $this->config = $config;
    }

    public function OrderQuery($order_sn,$store_no,$Config){
        $url = 'https://pay.wangfupay.com/api/v2/pay/query';
        $key = $Config['key'];
        $payOrderId = $store_no;// 支付订单号
        $mchOrderNo = $order_sn;// 商户订单号
        $reqTime = time();// 请求时间
        $signType = 'MD5';//签名类型当前支持
        $mchNo = $Config['mch_id'];
        $version = '2.0';// 版本号
        $data = [
            'payOrderId' => $payOrderId,
            'mchOrderNo' => $mchOrderNo,
            'reqTime' => $reqTime,
            'signType' => $signType,
            'mchNo' => $mchNo,
            'version' => $version,
        ];
        $data['sign'] = $this->getSign($data, $key);
        $response = $this->get_curl_request($url, $data);
        if($response['code'] != 0){
            $logRtx = new LogRepository("user_order_sn_check");
            $logRtx->log("fanhuierr:", json_encode($response, JSON_UNESCAPED_UNICODE));
            $logRtx->File();
        }
        return $response['data'];
    }



    /**
     * @param $orderSn
     * @param $money
     * @param $body
     * @param $attach
     * @return mixed
     */

    public function WxPayXCX($orderSn, $money, $body, $attach)
    {
        $wxConfig = $this->config;
        $key = $wxConfig['key'];
        $amount = abs(floatval($money)) * 100;// 微信支付 单位为分
        $body = $attach;
        $cashierType = $wxConfig['PayType'];
        $currency = "CNY";
        $mchNo = $wxConfig['mch_id'];
        $mchOrderNo = $orderSn;
        $notifyUrl = $wxConfig['notify_url'];
        $reqTime = time();
        $sellerRemark = "备注";
        $signType = "MD5";
//        $details = $attach;
        $subject = $wxConfig['app_name'];
        $version = "2.0";
        $data = [
            'version' => $version,
            'amount' => $amount,
            'body' => $body,
            'cashierType' => $cashierType,
            'currency' => $currency,
            'mchNo' => $mchNo,
            'mchOrderNo' => $mchOrderNo,
            'notifyUrl' => $notifyUrl,
            'reqTime' => $reqTime,
            'sellerRemark' => $sellerRemark,
            'signType' => $signType,
            'subject' => $subject,
//            'details' => $details,
            'sign'   => null
        ];
        // 加密
        $data['sign'] = $this->getSign($data, $key);
        $url = 'https://pay.wangfupay.com/api/v2/pay/unifiedOrder';
        $response = $this->get_curl_request($url, $data);
        if($response['code'] != 0 || $response['msg'] != "SUCCESS"){
            $logRtx = new LogRepository("user_order_sn_gather");
            $logRtx->log("return:", json_encode($response, JSON_UNESCAPED_UNICODE));
            $logRtx->File();
        }
        UserRecharge::query()->where('order_sn', $orderSn)->update([
            'store_no' => isset($response['data']['payOrderId']) ? $response['data']['payOrderId'] : ''
        ]);
        return  json_decode($response['data']['payUrl'],true)['qrUrl'];

    }

    /**
     * @param $orderSn
     * @param $money
     * @param $Config_id
     * @param $Config
     * @return mixed
     */
    public function ailPayXCX($orderSn, $money, $Config_id, $Config)
    {
        $key = $Config['key'];
        $amount = abs(floatval($money)) * 100;// 微信支付 单位为分
        $body = json_encode(['business_id' =>$Config_id]);
        $cashierType = $Config['PayType'];
        $currency = "CNY";
        $mchNo = $Config['mch_id'];
        $mchOrderNo = $orderSn;
        $notifyUrl = $Config['notify_url'];
        $reqTime = time();
        $sellerRemark = "备注";
        $signType = "MD5";
//        $details = $attach;
        $subject = $Config['app_name'];
        $version = "2.0";
        $data = [
            'version' => $version,
            'amount' => $amount,
            'body' => $body,
            'cashierType' => $cashierType,
            'currency' => $currency,
            'mchNo' => $mchNo,
            'mchOrderNo' => $mchOrderNo,
            'notifyUrl' => $notifyUrl,
            'reqTime' => $reqTime,
            'sellerRemark' => $sellerRemark,
            'signType' => $signType,
            'subject' => $subject,
//            'details' => $details,
            'sign'   => null
        ];
        // 加密
//        log::info(json_encode($data));
        $data['sign'] = $this->getSign($data, $key);
        $url = 'https://pay.wangfupay.com/api/v2/pay/unifiedOrder';
        $response = $this->get_curl_request($url, $data);
//        $logRtx = new LogRepository("ail_user_order_sn_gather");
//        $logRtx->log("return:", $response);
//        $logRtx->File();
        if($response['code'] != 0 || $response['msg'] != "SUCCESS"){
            $logRtx = new LogRepository("ail_user_order_sn_gather");
            $logRtx->log("return:", $response);
            $logRtx->File();
        }
//        log::info($response['data']);
//        log::info(json_decode($response['data']));
        UserRecharge::query()->where('order_sn', $orderSn)->update([
            'store_no' => isset($response['data']['payOrderId']) ? $response['data']['payOrderId'] : ''
        ]);
        return $response['data']['payUrl'];
    }

    /**
     * @param $url
     * @param $data
     * @return mixed
     */
    public static function get_curl_request($url, $data)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($curl, CURLOPT_HTTPHEADER, array(
            'Content-Type: application/json;charset=utf-8', 'Accept: application/json'
        ));
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($curl);
        curl_close($curl);
        return json_decode($output, true);

    }

    /**
     * @param $params
     * @param $key
     * //    加密方式说明：
     * //1.  参数排序方式为ASCII大小升序；
     * //2.  参数键与键之间使用&连接 （最外层）；
     * //3.  键与值之间使用=连接；
     * //4.  空值和sign不参与签名；
     * //5.  在加签串最后加上&key=密钥；
     * //6.  加签串转成UTF-8编码二进制；
     * //7.  进行MD5加密；
     * //8.  对加密后的二进制转大写十六进制字符串 。
     * @return string
     */
   public function getSign($params, $key)
    {
        $sortedKeys = [];
        foreach (array_keys($params) as $k) {
            if ($k !== 'sign' && !is_null($params[$k]) && $params[$k] !== '') {
                $sortedKeys[] = $k;
            }
        }
        sort($sortedKeys);
        // 构建签名字符串
        $signStr = '';
        foreach ($sortedKeys as $k) {
            $signStr .= $k . '=' . $params[$k] . '&';
        }
        $signStr .= 'key=' . $key;

        // 计算 MD5 签名
        $signBytes = $signStr;
        $digest = md5($signBytes, true); // true 表示返回原始二进制数据

        // 转换为十六进制字符串
        $hexString = '';
        for ($i = 0; $i < strlen($digest); $i++) {
            $hex = strtoupper(dechex(ord($digest[$i])));
            if (strlen($hex) == 1) {
                $hexString .= '0';
            }
            $hexString .= $hex;
        }
        return $hexString;
            //  别人demo 的 java 代码  转 我们PHP 代码
        ////        List<String> sortedKeys = new ArrayList<>();
//        for (String k :params . keyset()){
//            if (!k . equals("sign") && params . get(k) != null && !params . get(k) . isEmpty()) {
//                sortedKeys . add(k);
//            }
//        }
//        Collections . sort(sortedKeys);
//
//        StringBuilder signstr = new StringBuilder();
//        for (string k :sortedKeys){
//            signstr . append(k) . append("=") . append(params . get(k)) . append("&");
//        }
//        signstr . append("key=") . append(key);
//
//        byte[] signBytes = signstr . tostring() . getBytes(standardcharsets . UTF_8);
//
//        MessageDigest md = MessageDigest . getInstance(algorithm: "MD5"),bytel] digest = md . digest(signBytes);
//        StringBuilder hexString = new StringBuilder();
//        for (byte b : digest){
//            String hex = Integer . toHexString(i:xFF & b);
//        if (hex . length() == 1) {
//            hexString . append('0');
//        }
//            hexString . append(hex);
//        }
//        return hexstring . tostring() . toUpperCase();


    }

    // 将数组转成uri字符串
    function formatBizQueryParaMap($paraMap, $urlencode)
    {
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v) {
            if ($urlencode) {
                $v = urlencode($v);
            }
            $buff .= strtolower($k) . "=" . $v . "&";
        }

        if (strlen($buff) > 0) {
            $reqPar = substr($buff, 0, strlen($buff) - 1);
        }
        return $reqPar;
    }

    // 获取指定长度的随机字符串
    function getRandChar($length)
    {
        $str = null;
        $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
        $max = strlen($strPol) - 1;

        for ($i = 0; $i < $length; $i++) {
            $str .= $strPol [rand(0, $max)]; // rand($min,$max)生成介于min和max两个数之间的一个随机整数
        }

        return $str;
    }

    //获取当前服务器的IP
    function get_client_ip()
    {
        if ($_SERVER ['REMOTE_ADDR']) {
            $cip = $_SERVER ['REMOTE_ADDR'];
        } elseif (getenv("REMOTE_ADDR")) {
            $cip = getenv("REMOTE_ADDR");
        } elseif (getenv("HTTP_CLIENT_IP")) {
            $cip = getenv("HTTP_CLIENT_IP");
        } else {
            $cip = "unknown";
        }
        return $cip;
    }
}
